package za.org.jcicada.syshealth;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;

import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.entity.EntityCollection;
import org.jfree.chart.plot.CrosshairState;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.LookupPaintScale;
import org.jfree.chart.renderer.xy.AbstractXYItemRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYItemRendererState;
import org.jfree.data.xy.XYDataset;
import org.jfree.util.PublicCloneable;

import za.org.jcicada.genss.sensor.SensorStatus;

public class TimeStatusRenderer extends AbstractXYItemRenderer implements
		XYItemRenderer, Cloneable, PublicCloneable, Serializable {

	private static final long serialVersionUID = 1L;
	
	private static final LookupPaintScale paintScale;
	
	private static void addStatus(SensorStatus status) {
		Color colour = SensorColourMap.colourMap.get(status);
		paintScale.add(status.ordinal(), new Color(colour.getRed(), colour.getGreen(), colour.getBlue(), 128));
	}
	
	static {
		paintScale = new LookupPaintScale(0, SensorStatus.values().length, Color.GRAY);
		for (SensorStatus status : SensorStatus.values()) {
			addStatus(status);
		}
	}

	public void drawItem(Graphics2D g2, XYItemRendererState state,
			Rectangle2D dataArea, PlotRenderingInfo info, XYPlot plot,
			ValueAxis domainAxis, ValueAxis rangeAxis, XYDataset dataset, int series, int item,
			CrosshairState crosshairState, int pass) {

		double x = dataset.getXValue(series, item);
		double y0 = dataset.getYValue(series, Math.max(item - 1, 0));
		Paint p = paintScale.getPaint(y0);
		
		// get the previous point so we can fill since then
		double x0 = dataset.getXValue(series, Math.max(item - 1, 0));

		double xx0 = domainAxis.valueToJava2D(x0, dataArea, plot.getDomainAxisEdge());
		double yy0 = rangeAxis.valueToJava2D(plot.getRangeAxis().getLowerBound(), dataArea, plot.getRangeAxisEdge());
		double xx1 = domainAxis.valueToJava2D(x, dataArea, plot.getDomainAxisEdge());
		double yy1 = rangeAxis.valueToJava2D(plot.getRangeAxis().getUpperBound(), dataArea, plot.getRangeAxisEdge());

		Rectangle2D block;
		PlotOrientation orientation = plot.getOrientation();
		block = drawBlock(g2, p, orientation, yy0, xx0, yy1, xx1);
		
		if (dataset.getItemCount(series) == item + 1) {
			p = paintScale.getPaint(dataset.getYValue(series, item));
			double xx2 = dataArea.getMaxX();
			block = drawBlock(g2, p, orientation, yy0, xx1, yy1, xx2);
		}

		EntityCollection entities = state.getEntityCollection();
		if (entities != null) {
			addEntity(entities, block, dataset, series, item, 0.0, 0.0);
		}
	}

	private Rectangle2D drawBlock(Graphics2D g2, Paint p, PlotOrientation orientation,
			double y0, double x0, double y1, double x1) {
		Rectangle2D block;
		if (orientation.equals(PlotOrientation.HORIZONTAL)) {
			block = new Rectangle2D.Double(Math.min(y0, y1), Math.min(x0, x1), Math.abs(y1 - y0), Math.abs(x0 - x1));
		} else {
			block = new Rectangle2D.Double(Math.min(x0, x1), Math.min(y0, y1), Math.abs(x1 - x0), Math.abs(y1 - y0));
		}

		g2.setPaint(p);
		g2.fill(block);
		g2.setStroke(new BasicStroke(0.0f));
		g2.draw(block);
		return block;
	}

	/**
	 * Returns a clone of this renderer.
	 * 
	 * @return A clone of this renderer.
	 * 
	 * @throws CloneNotSupportedException
	 *             if there is a problem creating the clone.
	 */
	public Object clone() throws CloneNotSupportedException {
		TimeStatusRenderer clone = (TimeStatusRenderer) super.clone();
		return clone;
	}
}
